#include "sphere.h"

sphere::sphere()
{

}
/**
 * @brief dot((A+t*B-C),(A+t*B-C))=R*R
 *        t*t*dot(B,B)+2*t*dot(B,A-c)+dot(A-c,A-c)-R*R=0
 * @param r
 * @param tmin
 * @param tmax
 * @param rec
 * @return
 */
bool sphere::hit(const ray &r, float tmin, float tmax, hit_record &rec) const
{
    QVector3D oc=r.origin()-center;
    float a=QVector3D::dotProduct(r.direction(),r.direction());
    float b=QVector3D::dotProduct(oc,r.direction());
    float c=QVector3D::dotProduct(oc,oc)-radius*radius;
    float discriminant=b*b-a*c;
    rec.mat_ptr=mat;
    if(discriminant>0)
    {
        float temp=(-b-sqrt(b*b-a*c))/a;
        if(temp<tmax&&temp>tmin)
        {
            rec.t=temp;
            rec.p=r.point_at_parameter(rec.t);
            rec.normal=(rec.p-center)/radius;
            return true;
        }
        temp=(-b+sqrt(b*b-a*c))/a;
        if(temp<tmax&&temp>tmin)
        {
            rec.t=temp;
            rec.p=r.point_at_parameter(rec.t);
            rec.normal=(rec.p-center)/radius;
            return true;
        }

    }
    return false;
}

bool sphere::bounding_box(float t0, float t1, aabb &box) const
{
    box=aabb(center-QVector3D(radius,radius,radius),center+QVector3D(radius,radius,radius));
    return true;
}
